package org.fuxia.im.common;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;

import org.fuxia.im.core.ECMessageType;
import org.fuxia.im.core.entries.ECPacket;
import org.fuxia.im.core.socket.FileTransferCallBack;
import org.fuxia.im.core.socket.FileTransferScoketServer;
import org.fuxia.im.gui.Chat;

import sun.awt.shell.ShellFolder;

public class FileTranferPanel {

	public static MyFilePanel newPanel(File file, String fileNameStr,
			String fileSizeString, boolean isReceiveSide) {
		MyFilePanel filePanel = new MyFilePanel(file, fileNameStr,
				fileSizeString, isReceiveSide);

		return filePanel;
	}

	public static class MyFilePanel extends JPanel {
		private static final long serialVersionUID = 7950611379776736782L;
		private boolean isReceiveSide;
		private Chat owner;
		private long fileSize;

		private JPanel panel;
		private JLabel label;
		private JButton close;
		private JPanel fileInfo;
		private JLabel fileIcon;
		private JProgressBar progressBar;
		private JButton receive;
		private JButton saveAs;

		private Icon defaultIcon;

		public MyFilePanel(final File file, final String fileNameStr,
				final String fileSizeString, final boolean isReceiveSide) {
			// filePanel.setSize(289, 523);
			GridBagLayout gridBagLayout = new GridBagLayout();
			gridBagLayout.columnWidths = new int[] { 273, 0 };
			gridBagLayout.rowHeights = new int[] { 21, 85, 24, 0 };
			gridBagLayout.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
			gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0,
					Double.MIN_VALUE };
			this.setLayout(gridBagLayout);

			panel = new JPanel();
			panel.setBorder(new BevelBorder(BevelBorder.RAISED, null, null,
					null, null));
			GridBagConstraints gbc_panel = new GridBagConstraints();
			gbc_panel.fill = GridBagConstraints.BOTH;
			gbc_panel.gridx = 0;
			gbc_panel.gridy = 0;
			this.add(panel, gbc_panel);
			panel.setLayout(null);

			label = new JLabel("\u4F20\u8F93\u6587\u4EF6");
			label.setFont(new Font("微软雅黑", Font.PLAIN, 12));
			label.setBounds(0, 0, 65, 21);
			panel.add(label);

			close = new JButton("");
			defaultIcon = new ImageIcon(Thread.currentThread()
					.getContextClassLoader().getResource("images/close.jpg"));
			close.setOpaque(false);
			close.setBackground(new Color(2, 2, 2));
			close.setIcon(defaultIcon);
			close.addMouseListener(new MouseAdapter() {

				@Override
				public void mouseClicked(MouseEvent e) {
					getOwner().closeFileSendPane();
				}

				@Override
				public void mouseEntered(MouseEvent e) {
					Icon newIcon = new ImageIcon(Thread.currentThread()
							.getContextClassLoader()
							.getResource("images/focusclose.jpg"));
					close.setIcon(newIcon);
				}

				@Override
				public void mouseExited(MouseEvent e) {
					close.setIcon(defaultIcon);
				}

			});
			close.setBounds(250, 0, 21, 21);
			close.setBorder(new EmptyBorder(new Insets(0, 0, 0, 0)));
			panel.add(close);

			fileInfo = new JPanel();
			GridBagConstraints gbc_fileInfo = new GridBagConstraints();
			gbc_fileInfo.fill = GridBagConstraints.BOTH;
			gbc_fileInfo.insets = new Insets(0, 0, 5, 0);
			gbc_fileInfo.gridx = 0;
			gbc_fileInfo.gridy = 1;
			this.add(fileInfo, gbc_fileInfo);
			fileInfo.setLayout(null);

			fileIcon = new JLabel("");
			fileIcon.setBounds(10, 10, 38, 31);
			Icon icon = null;
			if (System.getProperty("os.name").toUpperCase().contains("WIN")) {
				try {
					ShellFolder shell = ShellFolder.getShellFolder(file);
					icon = new ImageIcon(shell.getIcon(true));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			} else {
				icon = new JFileChooser().getFileSystemView().getSystemIcon(
						file);
			}
			if (icon != null) {
				fileIcon.setIcon(icon);
			}
			fileInfo.add(fileIcon);

			JLabel fileReqLab = new JLabel(
					"\u53D1\u9001\u6587\u4EF6\u8BF7\u6C42:");
			fileReqLab.setFont(new Font("微软雅黑", Font.BOLD, 12));
			fileReqLab.setEnabled(false);
			fileReqLab.setForeground(SystemColor.textHighlight);
			fileReqLab.setBounds(65, 8, 85, 15);
			fileInfo.add(fileReqLab);

			JLabel fileName = new JLabel(fileNameStr);
			fileName.setFont(new Font("微软雅黑", Font.PLAIN, 12));
			fileName.setBounds(65, 26, 198, 15);
			fileInfo.add(fileName);

			progressBar = new JProgressBar();
			progressBar.setBounds(10, 51, 253, 14);
			progressBar.setStringPainted(true);
			progressBar.setValue(0);
			fileInfo.add(progressBar);

			long size = Long.parseLong(fileSizeString);
			String fileSizeStr = null;
			if (size / 1024 > 1024) {
				fileSizeStr = (size / (1024 * 1024)) + "MB";
			} else {
				fileSizeStr = (size / 1024) + "KB";
			}
			setFileSize(size);
			JLabel fileSizeLab = new JLabel(fileSizeStr);
			fileSizeLab.setFont(new Font("微软雅黑", Font.PLAIN, 12));
			fileSizeLab.setBounds(209, 67, 54, 15);
			fileInfo.add(fileSizeLab);

			JPanel optionPanel = new JPanel();
			GridBagConstraints gbc_optionPanel = new GridBagConstraints();
			gbc_optionPanel.fill = GridBagConstraints.BOTH;
			gbc_optionPanel.gridx = 0;
			gbc_optionPanel.gridy = 2;
			this.add(optionPanel, gbc_optionPanel);
			optionPanel.setLayout(null);

			receive = new JButton("\u63A5\u6536");
			receive.setBounds(10, 0, 57, 23);
			receive.setMargin(new Insets(0, 0, 0, 0));
			receive.setVisible(isReceiveSide);
			receive.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							String filePath = MessageFormat.format(
									ClientContext.getValue("file-save-path")
									.toString(), ClientContext
									.getLoginUser().getUserCode());
							File dir = new File(filePath);
							if (!dir.exists()) {
								dir.getParentFile().mkdirs();
								dir.mkdir();
							}

							File saveFile = new File(dir, fileNameStr
									+ file.getName().substring(
											file.getName().lastIndexOf(".")));
							if (!saveFile.exists()) {
								try {
									saveFile.createNewFile();
								} catch (IOException e) {
									e.printStackTrace();
								}
							}
							FileTransferScoketServer server = null;
							try {
								server = FileTransferScoketServer.newInstance();
								ClientContext.putValue("fserver-"
										+ getOwner().getUser().getUserCode(),
										server);
								ECPacket fAck = new ECPacket();
								fAck.setMessageType(ECMessageType.FILE_TRANSFER_ACK
										.name());
								fAck.addParam("ip", server.getIpAddress());
								fAck.addParam("port",
										String.valueOf(server.getPort()));
								fAck.setFrom(ClientContext.getLoginUser()
										.getUserCode());
								fAck.setTo(getOwner().getUser().getUserCode());
								ClientContext.getContext().getClient()
								.sendMessage(fAck);
							} catch (Exception e) {
								e.printStackTrace();
							}
							server.setFile(saveFile);
							server.setCallBack(new FileTransferCallBack() {
								public void callBack(final Object args) {
									SwingUtilities.invokeLater(new Runnable() {
										
										public void run() {
											if (args.getClass().isAssignableFrom(
													String.class)) {
												Object obj = ClientContext
														.removeKey("fserver-"
																+ getOwner().getUser()
																.getUserCode());
												if (obj != null) {
													((FileTransferScoketServer) obj)
													.shutdown();
												}
												getOwner().closeFileSendPane();
												getOwner().insertSuccessMessage(
														"文件接收成功");
											} else {
												updateProperties(((Long) args)
														.longValue());
											}
											
										}
									});
								}
							});
							new Thread(server).start();

						}
					});
				}
			});
			optionPanel.add(receive);

			saveAs = new JButton("\u53E6\u5B58\u4E3A");
			saveAs.setBounds(68, 0, 68, 23);
			saveAs.setMargin(new Insets(0, 0, 0, 0));
			saveAs.setVisible(isReceiveSide);
			saveAs.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					JFileChooser fileChooser = new JFileChooser();
					fileChooser.showSaveDialog(owner);
				}
			});
			optionPanel.add(saveAs);

			JButton cancel = new JButton(isReceiveSide ? "拒绝" : "取消");
			cancel.setMargin(new Insets(0, 0, 0, 0));
			cancel.setBounds(206, 0, 57, 23);
			cancel.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							ECPacket ack = new ECPacket();
							ack.setMessageType(ECMessageType.CANCEL_FILE_TRANSFER
									.name());
							ack.setFrom(ClientContext.getLoginUser()
									.getUserCode());
							ack.setTo(owner.getUser().getUserCode());
							if (isReceiveSide) {
								ack.addParam("info", "对方拒绝接收文件");
							} else {
								ack.addParam("info", "对方取消了文件发送");
							}
							try {
								ClientContext.getContext().getClient()
								.sendMessage(ack);
								owner.closeFileSendPane();
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					});
				}
			});
			optionPanel.add(cancel);
		}

		public boolean isReceiveSide() {
			return isReceiveSide;
		}

		public void setReceiveSide(boolean isReceiveSide) {
			this.isReceiveSide = isReceiveSide;
		}

		public Chat getOwner() {
			return owner;
		}

		public void setOwner(Chat owner) {
			this.owner = owner;
		}

		public long getFileSize() {
			return fileSize;
		}

		public void setFileSize(long fileSizeStr) {
			this.fileSize = fileSizeStr;
		}

		public void addReceiveButtionAction(ActionListener l) {
			this.receive.addActionListener(l);
		}

		public void addSaveAsButtonAction(ActionListener l) {
			this.saveAs.addActionListener(l);
		}

		public void updateProperties(final long count) {
			SwingUtilities.invokeLater(new Runnable() {
				
				public void run() {
					double cur = count;
					double fz = fileSize;
					progressBar.setValue((int) ((cur / fz) * 100));
					progressBar.repaint();
					
				}
			});
		}

	}
}
